Shadow mode's writable-PTs should only allow guest kernels access to PTs
authormaf46@burn.cl.cam.ac.uk <maf46@burn.cl.cam.ac.uk>
Tue, 19 Jul 2005 10:40:26 +0000 (10:40 +0000)
committermaf46@burn.cl.cam.ac.uk <maf46@burn.cl.cam.ac.uk>
Tue, 19 Jul 2005 10:40:26 +0000 (10:40 +0000)
xen/arch/x86/shadow.c
xen/arch/x86/shadow32.c
xen/include/asm-x86/shadow.h

index 1d0740608970045a869d61015ef6ab1f7940d50a..3f172d8647334e00db933d6e69a9c0f121d8d321 100644 (file)
@@ -1684,7 +1684,7 @@ static int shadow_fault_32(unsigned long va, struct cpu_user_regs *regs)
 
         if ( unlikely(!(l1e_get_flags(gpte) & _PAGE_RW)) )
         {
-            if ( shadow_mode_page_writable(d, l1e_get_pfn(gpte)) )
+            if ( shadow_mode_page_writable(va, regs, l1e_get_pfn(gpte)) )
             {
                 allow_writes = 1;
                 l1e_add_flags(gpte, _PAGE_RW);
index 7b53efcfc6061a4d1ac23968155a571c82e55d3a..0c0f749401a9de55060e871f6187fd4b5249bd90 100644 (file)
@@ -2612,7 +2612,7 @@ int shadow_fault(unsigned long va, struct cpu_user_regs *regs)
 
         if ( unlikely(!(l1e_get_flags(gpte) & _PAGE_RW)) )
         {
-            if ( shadow_mode_page_writable(d, l1e_get_pfn(gpte)) )
+            if ( shadow_mode_page_writable(va, regs, l1e_get_pfn(gpte)) )
             {
                 allow_writes = 1;
                 l1e_add_flags(gpte, _PAGE_RW);
index b4a5391ddcae52a9a69a39b2ee4c1a1f1bff3dfb..2ead58f983166d23c7b8b48571039fb8ffb667f1 100644 (file)
@@ -1691,8 +1691,10 @@ shadow_set_l1e(unsigned long va, l1_pgentry_t new_spte, int create_l1_shadow)
 /************************************************************************/
 
 static inline int
-shadow_mode_page_writable(struct domain *d, unsigned long gpfn)
+shadow_mode_page_writable(unsigned long va, struct cpu_user_regs *regs, unsigned long gpfn)
 {
+    struct vcpu *v = current;
+    struct domain *d = v->domain;
     unsigned long mfn = __gpfn_to_mfn(d, gpfn);
     u32 type = frame_table[mfn].u.inuse.type_info & PGT_type_mask;
 
@@ -1701,11 +1703,14 @@ shadow_mode_page_writable(struct domain *d, unsigned long gpfn)
         type = shadow_max_pgtable_type(d, gpfn, NULL);
 
     if ( VM_ASSIST(d, VMASST_TYPE_writable_pagetables) &&
-         (type == PGT_l1_page_table) )
+         (type == PGT_l1_page_table) &&
+         (va < HYPERVISOR_VIRT_START) &&
+         KERNEL_MODE(v, regs) )
         return 1;
 
     if ( shadow_mode_write_all(d) &&
-         type && (type <= PGT_l4_page_table) )
+         type && (type <= PGT_l4_page_table) &&
+         KERNEL_MODE(v, regs) )
         return 1;
 
     return 0;